package com.water.app.Impl.Goods;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.water.app.*;
import com.water.app.interfaces.Goods.GoodsService;
import com.water.app.mapper.goodsMapper;
import org.apache.commons.beanutils.BeanUtils;
import org.redisson.ScanResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    goodsMapper goodsMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    ObjectMapper objectMapper;
    public static final Logger log= LoggerFactory.getLogger(GoodsServiceImpl.class);


    @Override
    public Set<Goods> SelectAllGoods() {
        return new HashSet<>(goodsMapper.selectAllGoods());
    }

    @Override
    public List<String> selectByAllType() {
        Set<String> type = stringRedisTemplate.opsForSet().members(Constant.TYPE);
        if(type==null||type.isEmpty()){
            try {
                type= Set.copyOf(goodsMapper.selectByAllType());
                stringRedisTemplate.opsForSet().add(Constant.TYPE, type.toArray(new String[0]));
                stringRedisTemplate.expire(Constant.TYPE, 1, TimeUnit.HOURS);
                return new ArrayList<>(type);
            } catch (Exception e) {
                log.warn("数据库查询分类失败，返回空列表", e);
                return new ArrayList<>();
            }
        }
        return new ArrayList<>(type);
    }

    @Override
    public List<Goods> selectByLike(String likeName) {

        return  goodsMapper.selectByLike(likeName);

    }

    @Override
    public List<Goods> selectBySort() {
        return goodsMapper.selectBySort();
    }

    @Override
    public Result selectSKill() {
        ObjectMapper objectMapper = new ObjectMapper();
        if (stringRedisTemplate.hasKey(Constant.SKILL)){
            Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(Constant.SKILL);
            if (!entries.isEmpty()){
                List<Goods> list = entries.values().stream().map(o -> {
                    try {
                        return objectMapper.readValue(o.toString(), Goods.class);
                    } catch (JsonProcessingException e) {
                        log.error("反序列化失败: {}", o, e);
                        throw new IllegalArgumentException("商品数据异常", e);
                    }
                }).toList();
                return Result.success(list);
            }
        }
        List<Goods> list = goodsMapper.sKill();
        if(list!=null&&!list.isEmpty()){
            stringRedisTemplate.opsForHash().putAll(Constant.SKILL, list.stream().collect(Collectors.toMap(Goods::getId, o -> {
                try {
                    return objectMapper.writeValueAsString(o);
                } catch (JsonProcessingException e) {
                    log.error("序列化失败: {}", o, e);
                    throw new IllegalArgumentException("商品数据异常", e);
                }
            })));
        }
        return Result.success(list);
    }

    @Override
    public List<Goods> selectByType(Integer type) {
        return goodsMapper.selectByType(type);
    }

    @Override
    public Goods selectById(int goodsId) {
        return goodsMapper.selectById(goodsId);
    }

    @Override
    public List<Goods> selectAllByShopId(Integer shopId) {
        return goodsMapper.selectAllByShopId(shopId);
    }

    @Override
    public List<Type> selectAllType() {
        return goodsMapper.selectType();
    }

    @Override
    public selectByLike selectByLikeManager(String name,Integer type,Integer status,Integer pageSize,Integer page) {

        selectByLike selectByLike=new selectByLike();
        selectByLike.setGoodsList(goodsMapper.selectByLikeManager(name,type,status,pageSize,(page-1)*pageSize));
        selectByLike.setPage(goodsMapper.selectPage(name,type,status,pageSize));
        return selectByLike;
    }
}
